module stepgen(clk, enable, position, velocity, dirtime, steptime, step, dir, tap);
`define STATE_STEP 0
`define STATE_DIRCHANGE 1
`define STATE_DIRWAIT 2
//我发现这里的parameter和main.v的parameter是不一至的。 
parameter W=12;
parameter F=10;
parameter T=5;

input clk, enable;
output [W+F-1:0] position; reg [W+F-1:0] position;
input [F:0] velocity;
input [T-1:0] dirtime, steptime;
input [1:0] tap;

output step, dir;
reg step, dir;

reg [T-1:0] timer;
reg [1:0] state;
reg ones;
/*我认为这个ones只是一个暂时的标记，暂时记录了pbit的状态。因为pbit的状态就是position[F]的状态。
这个思路还是借鉴到了stepgen.c中的那个stepgen->accum.pbit就相当于PICKOFF位的作用。也就是说，只要
pbit位从0变1或者从1变零了。都会出发一个step周期。*/
wire dbit = velocity[F];
wire pbit = (tap == 0 ? position[F] 
	    : (tap == 1 ? position[F+1]
	    : (tap == 2 ? position[F+2]
	    : position[F+3])));
//这个其实是在说，如果tap==0 那么pbit=position[F],如果tap=1，那么pbit=position[F+1]
//正常情况下我们只需要考虑tap==0的情况，这取决于用会对steplen参数的输入。
//因此pbit=position[F].因而pbit!=ones其实就是要开始一个周期的脉冲了---____
wire [W+F-1:0] xvelocity = {{W{velocity[F]}}, {1{velocity[F-1:0]}}};
/*这里其实是个位宽的扩展处理我们知道velocity这个信号其实是来自于pluto_step.comp中的write16(rate)
而rate是有符号的int型，我们假设rate=-2.那么rate=0xfffffffe（反码加一哦）.write16(0xfffffffe)其实
只是发送了0xfffe(这部分猜想需要验证)。但是这个依然表示-2.且从这里我们就可以判断。velocity[F]在负数为1,
正数时为0.那么如果我们要将这个两个字节的数字扩展位数，如果是负数就高位用1扩展，如果是正数就用0扩展高位。
所以这个操作是合理的，我们可以理解。
*/
`ifdef TESTING
// for testing:
initial position = 1'b0;
initial state = `STATE_STEP;
initial timer = 0;
initial dir = 0;
initial ones = 0;
`endif
 
always @(posedge clk) 
begin
  if(enable) 
  begin
	// $display("state=%d timer=%d position=%h velocity=%h dir=%d dbit=%d pbit=%d ones=%d", state, timer, position, xvelocity, dir, dbit, pbit, ones);
		if((dir != dbit) && (pbit == ones))//在方向位发生改变，并且正处于一个step周期--__中时
		begin
	    	if(state == `STATE_DIRCHANGE) 
		  	begin
				if(timer == 0) 
				begin
		        		dir <= dbit;
		        		timer <= dirtime;
		    			state <= `STATE_DIRWAIT;
		      	end 
		      	else 
		      	begin
		    			timer <= timer - 1'd1;
		        end
	    	end 
	    	else 
	    	begin
				if(timer == 0) 
				begin
		    			step <= 0;
		    			timer <= dirtime;
		    			state <= `STATE_DIRCHANGE;
				end 
				else 
				begin
		    		timer <= timer - 1'd1;
		 		end
	    	end
		end 
		else if(state == `STATE_DIRWAIT)
		begin
	       	if(timer == 0) 
		    begin
				state <= `STATE_STEP;
	    	end 
	    	else 
	    	begin
			timer <= timer - 1'd1;
	    	end
		end 
		else //在方向不发生改变dir==dbit或启动一个周期脉冲pbit!=ones,在state=='STATE_STEP时（模糊概念    ）
		begin
	       	if(timer == 0) 
		    begin
		      	if(pbit != ones) //我认为这里就是发脉冲高位的地方！！！
			   	begin
		    	ones <= pbit;
		    	step <= 1'd1;      //这里的steptime
		    	timer <= steptime;
				end else 
				begin
		    		step <= 0;
				end
	       	end 
	        else 
			begin
		      	timer <= timer - 1'd1;
	        end
            if(dir == dbit)  
              	position <= position + xvelocity;//这个不可能每个脉冲执行一次。
       	end
	end
end
endmodule